package com.yanqu.road.server.manger.specialcookboy;

import com.yanqu.road.entity.activity.ActivityConfig;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.specialcookboy.config.*;
import com.yanqu.road.entity.enums.eActivityType;
import com.yanqu.road.entity.enums.eMailType;
import com.yanqu.road.entity.specialcookboy.ShareCodeUtil;
import com.yanqu.road.entity.specialcookboy.SpecialCookBoyUserData;
import com.yanqu.road.logic.bussiness.activity.SpecialCookBoyBusiness;

import com.yanqu.road.pb.specialcookboy.SpecialCookBoyProto;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.specialcookboy.SpecialCookBoyModule;
import com.yanqu.road.server.logic.mail.MailManager;
import com.yanqu.road.server.manger.ServerLanguageMgr;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.NormalActivityMgr;
import com.yanqu.road.server.manger.config.TaskMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.date.DateHelper;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

public class SpecialCookBoyMgr extends TempMgr {
    private static ActivityInfo activityInfo;

    private static SpecialCookBoyConfig config;

    private static Map<String, SpecialCookBoyProto.SpecialCookBoyConfigSync.Builder> configMsgMap;

    private static Map<Long, SpecialCookBoyUserData> userDataMap = new ConcurrentHashMap<>();

    @Override
    public boolean save() {
        for (SpecialCookBoyUserData userData : userDataMap.values()) {
            if (userData.isInsertOption()){
                SpecialCookBoyBusiness.addSpecialCookBoyUserData(userData);
            }else if (userData.isUpdateOption()){
                SpecialCookBoyBusiness.updateSpecialCookBoyUserData(userData);
            }
        }
        return true;
    }

    @Override
    public boolean reload() throws Exception {
        return super.reload();
    }

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        userDataMap = SpecialCookBoyBusiness.getSpecialCookBoyUserDataMap();
        return true;
    }

    @Override
    public boolean stop() {
        return true;
    }

    public static void reloadActivityData() {
        getLogger().info("reload specialCookBoy activity start");
        List<ActivityInfo> openActivityInfoList = NormalActivityMgr.getOpenActivityInfoList(eActivityType.SpecialCookBoy.getValue());
        if (openActivityInfoList.size() <= 0){
            getLogger().info("reload deepFishing activity finish, no activity in show time.");
            config = null;
            activityInfo = null;
            configMsgMap = null;
            return;
        }
        ActivityInfo tmpActivityInfo = openActivityInfoList.get(0);
        //活动配置
        Map<String, ActivityConfig> activityConfigMap = NormalActivityMgr.getActivityConfigMap(tmpActivityInfo.getActivityId());
        activityInfo = tmpActivityInfo;
        Map<Integer, SpecialCookBoyLevelConfig> tmpLevelConfig = SpecialCookBoyBusiness.getSpecialCookBoyLevelConfigList(activityInfo.getActivityId());
        List<SpecialCookBoyItemConfig> tmpItemConfig = SpecialCookBoyBusiness.getSpecialCookBoyItemConfigList(activityInfo.getActivityId());
        List<SpecialCookBoyEventConfig> tmpEventConfig = SpecialCookBoyBusiness.getSpecialCookBoyEventConfigList(activityInfo.getActivityId());
        Map<Integer,SpecialCookBoyPromptConfig> tmpPromptConfig = SpecialCookBoyBusiness.getSpecialCookBoyPromptConfigMap(activityInfo.getActivityId());
        Map<Integer, SpecialCookBoyChoosePassRoadEventConfig> tmpPassRoadChoose = SpecialCookBoyBusiness.getSpecialCookBoyChoosePassRoadEventConfigMap(activityInfo.getActivityId());
        List<SpecialCookBoyTipConfig> tmpTipDetailConfigList = SpecialCookBoyBusiness.getSpecialCookBoyTipConfigList(activityInfo.getActivityId());
        List<SpecialCookBoyGuideConfig> tmpSpecialCookBoyGuideConfigList = SpecialCookBoyBusiness.getSpecialCookBoyGuideConfigList(activityInfo.getActivityId());


        config = new SpecialCookBoyConfig(tmpLevelConfig, tmpItemConfig, tmpEventConfig, tmpPromptConfig,tmpPassRoadChoose,tmpTipDetailConfigList,tmpSpecialCookBoyGuideConfigList,activityConfigMap);

        configMsgMap = new ConcurrentHashMap<>();

        // 同步数据
        for (GamePlayer gamePlayer : GamePlayerMgr.getAllOnlinePlayer()) {
            SpecialCookBoyModule module = gamePlayer.getModule(SpecialCookBoyModule.class);
            module.syncConfig();
            module.checkLevelUnlock();
            module.checkShareCodeUseCountReset();
            module.updateTaskValue();
            module.syncUserData();
        }
        getLogger().info("reload specialCookBoy activity finish");
    }




    /**
     * 获取配置
     * @param language
     * @return
     */

    public static SpecialCookBoyProto.SpecialCookBoyConfigSync.Builder getConfigMsg(String language){
        if (configMsgMap.get(language) == null) {
            SpecialCookBoyProto.SpecialCookBoyConfigSync.Builder builder = initConfigMsg(config, language);
            configMsgMap.put(language, builder);
        }
        return configMsgMap.get(language);

    }

    /**
     * 初始化某种语言配置同步信息
     */
    public static SpecialCookBoyProto.SpecialCookBoyConfigSync.Builder initConfigMsg(SpecialCookBoyConfig config,String language){
        SpecialCookBoyProto.SpecialCookBoyConfigSync.Builder builder = SpecialCookBoyProto.SpecialCookBoyConfigSync.newBuilder();
        //关卡配置
        for (SpecialCookBoyLevelConfig levelConfig : config.getLevelConfigMap().values()) {
            SpecialCookBoyProto.SpecialCookBoyLevelConfig.Builder levelBuilder = SpecialCookBoyProto.SpecialCookBoyLevelConfig.newBuilder();
            levelBuilder.setLevelId(levelConfig.getLevelId());
            levelBuilder.setType(levelConfig.getType());
            levelBuilder.setName(ServerLanguageMgr.getContent(levelConfig.getName(),language));
            levelBuilder.setDesc(ServerLanguageMgr.getContent(levelConfig.getDesc(),language));
            levelBuilder.setOnceReward(levelConfig.getOnceReward());

            int unlock = levelConfig.getUnlock();
            int mainTaskIndex = TaskMgr.getMainTaskIndex(unlock);
            if (mainTaskIndex != -1){
                levelBuilder.setUnlock(mainTaskIndex);
            }else {
                levelBuilder.setUnlock(unlock-1000000);
            }

            levelBuilder.setTimeLimit(levelConfig.getTimeLimit());
            levelBuilder.setInitialValue(levelConfig.getInitialValue());
            levelBuilder.setTargetValue(levelConfig.getTargetValue());
            levelBuilder.setLevelOrder(levelConfig.getLevelOrder());

            builder.addLevelConfig(levelBuilder);
        }
        //道具配置
        for (SpecialCookBoyItemConfig itemConfig : config.getItemConfigList()) {
            SpecialCookBoyProto.SpecialCookBoyItemConfig.Builder itemBuilder = SpecialCookBoyProto.SpecialCookBoyItemConfig.newBuilder();

            itemBuilder.setLevelId(itemConfig.getLevelId());
            itemBuilder.setItemsort(itemConfig.getItemsort());
            itemBuilder.setName(ServerLanguageMgr.getContent(itemConfig.getName(),language));
            itemBuilder.setItemInteractiveType(itemConfig.getItemInteractiveType());
            itemBuilder.setIsSpine(itemConfig.getIsSpine());

            builder.addItemConfig(itemBuilder);
        }
        //事件配置
        for (SpecialCookBoyEventConfig eventConfig : config.getEventConfigList()) {
            SpecialCookBoyProto.SpecialCookBoyEventConfig.Builder eventBuilder = SpecialCookBoyProto.SpecialCookBoyEventConfig.newBuilder();

            eventBuilder.setLevelId(eventConfig.getLevelId());
            eventBuilder.setEventSort(eventConfig.getEventSort());
            eventBuilder.setInteractiveOne(eventConfig.getInteractiveOne());
            eventBuilder.setInteractiveTwo(eventConfig.getInteractiveTwo());
            eventBuilder.setInteractiveTextDesc(ServerLanguageMgr.getContent(eventConfig.getInteractiveTextDesc(),language));
            eventBuilder.setBubbleItem(eventConfig.getBubbleItem());
            eventBuilder.setWeight(eventConfig.getWeight());
            eventBuilder.setPredecessors(eventConfig.getPredecessors());
            eventBuilder.setBubbleOffset(eventConfig.getBubbleOffset());
            eventBuilder.setFailPredecessorsDesc(ServerLanguageMgr.getContent(eventConfig.getFailPredecessorsDesc(),language));

            builder.addEventConfig(eventBuilder);
        }
        //提示配置
        for (SpecialCookBoyPromptConfig promptConfig : config.getPromptConfigMap().values()) {
            SpecialCookBoyProto.SpecialCookBoyPromptConfig.Builder promptBuilder = SpecialCookBoyProto.SpecialCookBoyPromptConfig.newBuilder();

            promptBuilder.setLevelId(promptConfig.getLevelId());
            promptBuilder.setPromptSort(promptConfig.getPromptSort());
            promptBuilder.setPromptName(ServerLanguageMgr.getContent(promptConfig.getPromptName(),language));
            promptBuilder.setRecordId(promptConfig.getRecordId());
            builder.addPromptConfig(promptBuilder);
        }

        //贸易关卡替换配置
        for (SpecialCookBoyChoosePassRoadEventConfig specialCookBoyChoosePassRoadEventConfig: config.getPassRoadEventConfigMap().values()){
            SpecialCookBoyProto.SpecialCookBoyReplacePassRoadConfig.Builder replacePassRoadConfigBuilder = SpecialCookBoyProto.SpecialCookBoyReplacePassRoadConfig.newBuilder();
            replacePassRoadConfigBuilder.setEventId(specialCookBoyChoosePassRoadEventConfig.getEventId());
            replacePassRoadConfigBuilder.setType(specialCookBoyChoosePassRoadEventConfig.getType());
            replacePassRoadConfigBuilder.setName(ServerLanguageMgr.getContent(specialCookBoyChoosePassRoadEventConfig.getName(),language));
            replacePassRoadConfigBuilder.setDesc(ServerLanguageMgr.getContent(specialCookBoyChoosePassRoadEventConfig.getDesc(),language));
            replacePassRoadConfigBuilder.setReward(specialCookBoyChoosePassRoadEventConfig.getReward());
            replacePassRoadConfigBuilder.setParLists(specialCookBoyChoosePassRoadEventConfig.getParLists());

            builder.addReplacePassRoadConfig(replacePassRoadConfigBuilder);
        }

        //小当家详细提示配置
        for (SpecialCookBoyTipConfig tipConfig:config.getTipDetailConfigList()){
            SpecialCookBoyProto.SpecialCookBoyTipDetailConfig.Builder tipDetailConfigBuilder = SpecialCookBoyProto.SpecialCookBoyTipDetailConfig.newBuilder();
            tipDetailConfigBuilder.setLevelId(tipConfig.getLevelId());
            tipDetailConfigBuilder.setTipId(tipConfig.getTipId());
            tipDetailConfigBuilder.setHeadPortraitId(tipConfig.getHeadPortraitId());
            tipDetailConfigBuilder.setTaskCompleted(tipConfig.getTaskCompleted());
            tipDetailConfigBuilder.setTipDesc(ServerLanguageMgr.getContent(tipConfig.getTipDesc(),language));
            tipDetailConfigBuilder.setTipCoordinate(tipConfig.getTipCoordinate());
            tipDetailConfigBuilder.setTipTime(tipConfig.getTipTime());
            builder.addTipDetailConfig(tipDetailConfigBuilder);
        }

        for (SpecialCookBoyGuideConfig specialCookBoyGuideConfig: config.getGuideConfigList()){
            SpecialCookBoyProto.SpecialCookBoyGuideConfig.Builder guideConfigBuilder = SpecialCookBoyProto.SpecialCookBoyGuideConfig.newBuilder();
            guideConfigBuilder.setLevelId(specialCookBoyGuideConfig.getLevelId());
            guideConfigBuilder.setGuideType(specialCookBoyGuideConfig.getGuideType());
            guideConfigBuilder.setGuideId(specialCookBoyGuideConfig.getGuideId());
            guideConfigBuilder.setGuideDesc(ServerLanguageMgr.getContent(specialCookBoyGuideConfig.getGuideDesc(),language));
            guideConfigBuilder.setCharacterId(specialCookBoyGuideConfig.getCharacterId());
            guideConfigBuilder.setCharacterName(ServerLanguageMgr.getContent(specialCookBoyGuideConfig.getCharacterName(),language));
            builder.addGuideConfig(guideConfigBuilder);
        }
        return builder;
    }

    public static SpecialCookBoyConfig getConfig() {
        return config;
    }

    public static void setConfig(SpecialCookBoyConfig config) {
        SpecialCookBoyMgr.config = config;
    }

    public static ActivityInfo getActivityInfo() {
        return activityInfo;
    }

    public static SpecialCookBoyUserData getUserData(long playerId) {
        if (!userDataMap.containsKey(playerId)){
            return null;
        }
        return userDataMap.get(playerId);
    }

    /**
     * 获取玩家数据 不存在则新建
     * @param playerId
     * @return
     */

    public static SpecialCookBoyUserData getOrCreateUserData(long playerId) {
        if (userDataMap.get(playerId) == null) {
            synchronized (userDataMap){
                if (userDataMap.get(playerId) == null){
                    long now = System.currentTimeMillis();
                    SpecialCookBoyUserData specialCookBoyUserData = new SpecialCookBoyUserData();
                    specialCookBoyUserData.setUserId(playerId);
                    specialCookBoyUserData.setGuideBit(0);
                    specialCookBoyUserData.setPassInfo(initNewLevelPassInfo());
                    specialCookBoyUserData.setShareCode("");
                    specialCookBoyUserData.setShareCodeRefreshTime(0);
                    specialCookBoyUserData.setUsedOthersShareCode(new ArrayList<>());
                    specialCookBoyUserData.setLastResetUsedOthersShareCodeTime(now);
                    specialCookBoyUserData.setShareCodeUsePlayers(new ArrayList<>());
                    specialCookBoyUserData.setCurrentLevel(0);
                    specialCookBoyUserData.setIsShare(false);
                    specialCookBoyUserData.setUnlockedTips(new ArrayList<>());
                    specialCookBoyUserData.setInsertOption();
                    userDataMap.put(playerId, specialCookBoyUserData);
                }
            }
        }

        return userDataMap.get(playerId);
    }

    public static void addUserData(SpecialCookBoyUserData userData) {
        userDataMap.put(userData.getUserId(), userData);
    }

    /**
     * 初始化新的关卡通过信息
     * @return
     */

    public static Map<Integer,Integer> initNewLevelPassInfo(){
        Map<Integer,Integer> passInfo = new ConcurrentHashMap<>();
        for (SpecialCookBoyLevelConfig levelConfig : config.getLevelConfigMap().values()) {
            passInfo.put(levelConfig.getLevelId(),0);
        }
        return passInfo;
    }

    /**
     * 检测关卡解锁
     * @param userId
     * @param taskId
     * @return
     */

    public static boolean checkLevelUnlock(long userId,int taskId){
        if (config == null){
            return false;
        }
        SpecialCookBoyUserData userData = getOrCreateUserData(userId);
        if (userData == null){
            getLogger().error("SpecialCookBoyUserData is null,userId = {}",userId);
            return false;
        }
        for (Map.Entry<Integer, SpecialCookBoyLevelConfig>entry:config.getLevelConfigMap().entrySet()){
            Map<Integer, Integer> passInfo = userData.getPassInfo();
            if (!passInfo.containsKey(entry.getKey())){
                passInfo.put(entry.getKey(),0);
            }
            //如果没解锁的
            if (passInfo.get(entry.getKey())==0){
                int needId = entry.getValue().getUnlock();
                if (taskId >= needId){
                    passInfo.put(entry.getKey(),1);
                }
            }
            userData.setUpdateOption();
        }
        return true;
    }

    public static SpecialCookBoyLevelConfig getLevelConfig(int levelId){
        if (config == null){
            return null;
        }
        return config.getLevelConfigMap().get(levelId);
    }

    /**
     * 获取当日最新的邀请码
     * @param userId
     * @return
     */

    public static SpecialCookBoyProto.SpecialCookBoyUpdateShareCodeResp.Builder getNewestShareCode(long userId){
        SpecialCookBoyProto.SpecialCookBoyUpdateShareCodeResp.Builder builder = SpecialCookBoyProto.SpecialCookBoyUpdateShareCodeResp.newBuilder();
        if (activityInfo == null){
            builder.setRet(GameErrorCode.E_SPECIAL_COOK_BOY_NO_UNLOCK);
            return builder;
        }
        if (!ActivityMgr.activityInTime(activityInfo)){
            builder.setRet(GameErrorCode.E_SPECIAL_COOK_BOY_ACTIVITY_NO_OPEN);
            return builder;
        }
        SpecialCookBoyUserData userData = getUserData(userId);
        if (userData == null){
            builder.setRet(GameErrorCode.E_SPECIAL_COOK_BOY_NO_UNLOCK);
            return builder;
        }
        long shareCodeRefreshTime = userData.getShareCodeRefreshTime();
        long now = System.currentTimeMillis();
        if (!DateHelper.isSameDay(shareCodeRefreshTime / 1000, now /1000)){
            long zeroTimeStamp = DateHelper.getZeroTimeStamp(now);
            userData.setShareCode(generateShareCode(userId,zeroTimeStamp));
            userData.setShareCodeRefreshTime(zeroTimeStamp);
            //重置一下使用过的分享码
            userData.setShareCodeUsePlayers(new ArrayList<>());
            userData.setUpdateOption();
        }

        builder.setRet(0);
        builder.setShareCode(userData.getShareCode());
        builder.setLastRefreshShareCodeTime(userData.getShareCodeRefreshTime());
        return builder;
    }

    //通过userId加上时间戳生成一个特殊的分享码
    public static String generateShareCode(long userId,long zeroTimeStamp){
        return ShareCodeUtil.generateShareCode(userId,zeroTimeStamp);
    }

    //通过分享码解码获取userId
    public static long getUserIdByShareCode(String shareCode){
        return ShareCodeUtil.decodeShareCode(shareCode);
    }

    public static int useShareCode(long usePlayerId,long beUsePlayerId,String shareCode, String language){
        if (activityInfo == null){
            return GameErrorCode.E_SPECIAL_COOK_BOY_NO_UNLOCK;
        }
        if (!ActivityMgr.activityInTime(activityInfo)){
            return GameErrorCode.E_SPECIAL_COOK_BOY_ACTIVITY_NO_OPEN;
        }

        SpecialCookBoyUserData userData = getUserData(beUsePlayerId);
        if (userData == null){
            return GameErrorCode.E_SPECIAL_COOK_BOY_USER_NO_FOUND;
        }
        if (!Objects.equals(userData.getShareCode(),shareCode)){
            return GameErrorCode.E_SPECIAL_COOK_BOY_SHARE_CODE_ERROR;
        }
        if (!DateHelper.isSameDay(userData.getShareCodeRefreshTime() / 1000,System.currentTimeMillis() / 1000)){
            return GameErrorCode.E_SPECIAL_COOK_BOY_SHARE_CODE_OVER_TIME;
        }
        //如果邀请码被用的次数超过了最大次数
        synchronized (userData){
            List<Long> shareCodeUsePlayers = userData.getShareCodeUsePlayers();
            if (shareCodeUsePlayers.size() >= config.getCodeBeUsedMaxGetItem()){
                return GameErrorCode.E_SPECIAL_COOK_BOY_SHARE_CODE_BE_USE_TIME_LIMIT;
            }
            if (shareCodeUsePlayers.contains(usePlayerId)){
                return GameErrorCode.E_SPECIAL_COOK_BOY_SHARE_CODE_HAS_USE;
            }

            shareCodeUsePlayers.add(usePlayerId);
            userData.setUpdateOption();
        }

        //给被用的人发邮件
        String mailTitle = ServerLanguageMgr.getContent(config.getMailTitle(),language);
        String mailContent = ServerLanguageMgr.getContent(config.getMailContain(),language);
        MailManager.sendMail(beUsePlayerId, eMailType.SYSTEM.getValue(), config.getUseCodeReward(), mailContent, mailTitle);
        GamePlayer onlinePlayer = GamePlayerMgr.getOnlinePlayer(beUsePlayerId);
        if (onlinePlayer != null){
            onlinePlayer.getModule(SpecialCookBoyModule.class).syncUserData();
        }

        return 0;
    }

    public static SpecialCookBoyPromptConfig getSpecialCookBoyPromptConfigByRecordId(int recordId){
        if (config == null){
            return null;
        }
        return config.getPromptConfigMap().get(recordId);
    }

}
